package com.cybertron.am.wordpress.domain.woo;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author tomato
 * @date 2020/04/15
 **/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class WooProduct {

    private String id;

    private String name;

    private String slug;

    private String permalink;

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
    private Date dateCreated;

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
    private Date dateCreatedGmt;

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
    private Date dateModified;

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
    private Date dateModifiedGmt;

    /**
     * Product type. Options: simple, grouped, external and variable. Default is simple.
     */
    @Builder.Default
    private String type = "simple";

    /**
     * Product status (post status). Options: draft, pending, private and publish. Default is publish.
     */
    @Builder.Default
    private String status = "publish";

    private boolean featured;

    /**
     * Catalog visibility. Options: visible, catalog, search and hidden. Default is visible.
     */
    @Builder.Default
    private String catalogVisibility = "visible";

    private String description;

    private String shortDescription;

    private String sku;

    private String price;

    private String regularPrice;

    private String salePrice;

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
    private Date dateOnSaleFrom;

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
    private Date dateOnSaleFromGmt;

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
    private Date dateOnSaleTo;

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
    private Date dateOnSaleToGmt;

    private String priceHtml;

    private boolean onSale = true;

    private boolean purchasable;

    private Integer totalSales;

    private boolean virtual;

    private boolean downloadable;

    private List<Downloads> downloads;

    private Integer downloadLimit;

    private Integer downloadExpiry;

    private String taxStatus;

    private String taxClass;

    private boolean manageStock;

    private Integer stockQuantity;

    /**
     * Controls the stock status of the product. Options: instock, outofstock, onbackorder. Default is instock.
     */
    private String stockStatus;

    /**
     * If managing stock, this controls if backorders are allowed. Options: no, notify and yes. Default is no.
     */
    private String backorders;

    private boolean backordersAllowed;

    private boolean backordered;

    private boolean soldIndividually;

    private String weight;

    private Dimensions dimensions;

    private boolean shippingRequired;

    private boolean shippingTaxable;

    private String shippingClass;

    private Integer shippingClassId;

    @Builder.Default
    private boolean reviewsAllowed = true;

    private String averageRating;

    private Integer ratingCount;

    private List<Integer> relatedIds;

    private List<Integer> upsellIds;

    private List<Integer> crossSellIds;

    private Integer parentId;

    private String purchaseNote;

    private List<WooCategory> categories;

    private List<Image> images;

    private List<Attribute> attributes;
    private List<DefaultAttribute> defaultAttributes;

    private List<Integer> variations;

    private List<WooVariant> variants;

    private List<Map<String, String>> metaData;

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
    public static class Attribute {

        private Integer id;

        private String name;

        private String slug;

        private String type;

        private Integer position;

        @Builder.Default
        private boolean visible = true;

        @Builder.Default
        private boolean variation = true;

        private Set<String> options;

        private boolean hasArchives;
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
    public static class DefaultAttribute {

        private String name;

        private String option;
    }

    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
    public static class Image {

        private Integer id;

        @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
        private Date dateCreated;
        @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
        private Date dateCreatedGmt;
        @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
        private Date dateModified;
        @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
        private Date dateModifiedGmt;

        private String src;

        private String name;

        private String alt;
    }

    @Data
    @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
    public static class Dimensions {

        private String length;

        private String width;

        private String height;

    }

    @Data
    @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
    public static class Downloads {

        private String id;

        private String name;

        private String file;
    }
}
